﻿using ArtMath.Component.Point;
using ArtMath.Core.Data;
using ArtMath.PointCollection;
using ArtMath.Resource;
using ArtMath.Setting;
using System;
using System.Collections.Generic;
using System.Linq;
using ArtMath.CommonType;

namespace ArtMath.Component.Manager
{
    /// <summary>
    /// 交点管理器（自动）
    /// </summary>
    [Serializable]
    public class CrossoverPointsManager_A : CrossoverPointsManagerBase
    {
        public CrossoverPointsManager_A(SketchPad pad, string name, LineBase line1, LineBase line2, bool addToList = true) : base(pad, name, line1, line2, addToList)
        {

        }
        public bool CheckPointNameExist(string name)
        {
            foreach (CrossoverPointBase item in Points)
            {
                if (item.Name == name)
                {
                    return true;
                }
            }
            return false;
        }
        public override void InChildrenIterator(Predicate<ShapeBase> act)
        {
            if (act == null) return;
            foreach (CrossoverPointBase item in Points)
            {
                if (item != null)
                {
                    if (!act(item)) return;
                }
            }
        }
        public override void PointMoving_ManagedComponentsLimit(Base component)
        {
            Dictionary<CrossoverPointBase, PointD> dic = GetDistribution(out CrossoverPointBase[] rdpt, out PointD[] rdco);
            if (dic != null)
            {
                foreach (KeyValuePair<CrossoverPointBase, PointD> item in dic)
                {
                    item.Key.ObjectState = ObjectState.Normal;
                    item.Key.NewPxy = item.Value;
                }
                foreach (KeyValuePair<CrossoverPointBase, PointD> item in dic)
                {
                    item.Key.Move(item.Value, true);
                }
            }
            if (rdpt != null)
            {
                foreach (CrossoverPointBase item in rdpt)
                {
                    if (Settings.Instance.ManagerAutoDelete && item.IsIndependent)
                    {
                        item.Delete();
                        Points.Remove(item);
                    }
                    else
                    {
                        item.ObjectState = ObjectState.Deleted;
                    }
                }
            }
            if (rdco != null)
            {
                for (int i = 0; i < rdco.Length; i++)
                {
                    if (Settings.Instance.ManagerAutoAdd)
                    {
                        CrossoverPointBase pt;
                        string name = $"{Resources.Translate("CrossoverPoint")}{Points.Count + i + 1}";
                        if (Pad.CoordinateType == CoordinateSystemType.PolarCoordinate)
                        {
                            pt = new PCrossoverPoint(Pad, name, Line1, Line2, this, false);
                        }
                        else
                        {
                            pt = new RCrossoverPoint(Pad, name, Line1, Line2, this, false);
                        }
                        pt.NewPxy = rdco[i];
                        if (Pad.TryCreateObject(pt))
                        {
                            pt.OrderIndex = Pad.PointOrder++;
                            Points.Add(pt);
                        }
                        else
                        {
                            throw new PointMovingException(this, Resources.Translate("FailCreateNewCrossoverPoint"));
                        }
                    }
                }
            }
            //PointD[] tmp = CurveIntersection.GetCrossPoints(Line1, Line2);
            //bool[] flag = new bool[Points.Count];
            //if (tmp != null)
            //{
            //    for (int i = 0; i < tmp.Length; i++)
            //    {
            //        double minDist = double.PositiveInfinity;
            //        int minIndex = -1;
            //        for (int j = 0; j < flag.Length; j++)
            //        {
            //            if (!flag[j])
            //            {
            //                double dist = tmp[i].DistanceTo(Points[j].Pxy);
            //                if (dist < minDist)
            //                {
            //                    minDist = dist;
            //                    minIndex = j;
            //                }
            //            }
            //        }
            //        if (minIndex < 0)
            //        {
            //            if (Settings.Instance.ManagerAutoAdd)
            //            {
            //                RCrossoverPoint pt;
            //                string name = $"\"{Line1.Name}\"和\"{Line2.Name}\"的交点{i + 1}";
            //                if (Pad.CoordinateType == CoordinateSystemType.PolarCoordinate)
            //                {
            //                    pt = new SCrossoverPoint(Pad, name, Line1, Line2, false);
            //                }
            //                else
            //                {
            //                    pt = new RCrossoverPoint(Pad, name, Line1, Line2, false);
            //                }
            //                pt.NewPxy = tmp[i];
            //                if (Pad.TryCreateObject(pt, tmp[i]))
            //                {
            //                    pt.OrderIndex = Pad.PointOrder++;
            //                    Points.Add(pt);
            //                }
            //                //else
            //                //{
            //                //    throw new PointMovingException(this, $"新交点\"{pt.Name}\"创建失败，移动失败");
            //                //}
            //            }
            //        }
            //        else
            //        {
            //            Points[minIndex].Deleted = false;
            //            if (Points[minIndex].Flag)
            //            {
            //                if (Points[minIndex].NewPxy.AlmostEquals(tmp[i]))
            //                {
            //                    Points[minIndex].WaitToLimit.Remove(component as LineBase);
            //                }
            //                else
            //                {
            //                    throw new PointMovingException(this, $"\"{Points[minIndex].Name}\"有多个不同的目标坐标：{Pad.PxyToMath(Points[minIndex].NewPxy)}和{Pad.PxyToMath(tmp[i])}");
            //                }
            //            }
            //            else
            //            {
            //                Points[minIndex].Move(tmp[i]);
            //            }
            //            flag[minIndex] = true;
            //        }
            //    }
            //}
            //int delCnt = 0;
            //for (int i = 0; i < flag.Length; i++)
            //{
            //    if (!flag[i])
            //    {
            //        if (Settings.Instance.ManagerAutoDelete)
            //        {
            //            if (Points[i - delCnt].IsIndependent)
            //            {
            //                Points[i - delCnt].Delete();
            //                Points.RemoveAt(i - delCnt);
            //                delCnt++;
            //                continue;
            //            }
            //        }
            //        Points[i - delCnt].Deleted = true;
            //    }
            //}
        }
        //public override Base[] CheckNearBy(PointD Plocation)
        //{
        //    List<Base> objs = new List<Base>();
        //    foreach (RCrossoverPoint item in Points)
        //    {
        //        objs.AddRange(item.CheckNearBy(Plocation));
        //    }
        //    return objs.ToArray();
        //}
        public override void CreateComponents()
        {
            PointCollectionBase[] collections = PointCollectionBase.Intersect(Line1.Skeleton.PointCollections, Line2.Skeleton.PointCollections);
            if (collections != null)
            {
                List<PointD> cross = new List<PointD>();
                foreach (PointCollectionBase item in collections)
                {
                    DiscontinuityPoint dp = item as DiscontinuityPoint;
                    if (dp != null)
                    {
                        cross.AddRange(dp.Points);
                    }
                }
                CrossoverPointBase pt;
                for (int i = 0; i < cross.Count; i++)
                {
                    string name = $"{Resources.Translate("CrossoverPoint")}{i + 1}";
                    if (Pad.CoordinateType == CoordinateSystemType.PolarCoordinate)
                    {
                        pt = new PCrossoverPoint(Pad, name, Line1, Line2, this, false);
                    }
                    else
                    {
                        pt = new RCrossoverPoint(Pad, name, Line1, Line2, this, false);
                    }
                    pt.NewPxy = Pad.XYToPxy(cross[i]);//NewPxy赋值->base的ForceMove方法移动点到NewPxy处->坐标和Pxy得到更新
                    if (Pad.TryCreateObject(pt))
                    {
                        pt.OrderIndex = Pad.PointOrder++;
                        Points.Add(pt);
                    }
                }
            }
            base.CreateComponents();
        }
    }
}
